home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 6: Level 6 / 17 Bit - Level 6 (1998)(Epic Marketing)[!].iso / quartz / q0429.dms / q0429.adf / libray / libobj / box.c < prev    next >
C/C++ Source or Header  |  1991-08-08  |  3KB  |  157 lines

  1. /*
  2.  * box.c
  3.  *
  4.  * Copyright (C) 1989, 1991, Craig E. Kolb
  5.  * All rights reserved.
  6.  *
  7.  * This software may be freely copied, modified, and redistributed
  8.  * provided that this copyright notice is preserved on all copies.
  9.  *
  10.  * You may not distribute this software, in whole or in part, as part of
  11.  * any commercial product without the express consent of the authors.
  12.  *
  13.  * There is no warranty or other guarantee of fitness of this software
  14.  * for any purpose.  It is provided solely "as is".
  15.  *
  16.  * $Id: box.c,v 4.0 91/07/17 14:36:32 kolb Exp Locker: kolb $
  17.  *
  18.  * $Log:    box.c,v $
  19.  * Revision 4.0  91/07/17  14:36:32  kolb
  20.  * Initial version.
  21.  * 
  22.  */
  23. #include "geom.h"
  24. #include "box.h"
  25.  
  26. static Methods *iBoxMethods = NULL;
  27. static char boxName[] = "box";
  28.  
  29. unsigned long BoxTests, BoxHits;
  30.  
  31. Box *
  32. BoxCreate(v1, v2)
  33. Vector *v1, *v2;
  34. {
  35.     Box *box;
  36.     Vector size;
  37.  
  38.     VecSub(*v1, *v2, &size);
  39.  
  40.     if (equal(size.x, 0.) || equal(size.y, 0.) || equal(size.z, 0.)) {
  41.         RLerror(RL_WARN, "Degenerate box.\n");
  42.         return (Box *)NULL;
  43.     }
  44.  
  45.     box = (Box *)share_malloc(sizeof(Box));
  46.     box->bounds[LOW][X] = min(v1->x, v2->x);
  47.     box->bounds[HIGH][X] = max(v1->x, v2->x);
  48.     box->bounds[LOW][Y] = min(v1->y, v2->y);
  49.     box->bounds[HIGH][Y] = max(v1->y, v2->y);
  50.     box->bounds[LOW][Z] = min(v1->z, v2->z);
  51.     box->bounds[HIGH][Z] = max(v1->z, v2->z);
  52.     return box;
  53. }
  54.  
  55. Methods *
  56. BoxMethods()
  57. {
  58.     if (iBoxMethods == (Methods *)NULL) {
  59.         iBoxMethods = MethodsCreate();
  60.         iBoxMethods->create = (GeomCreateFunc *)BoxCreate;
  61.         iBoxMethods->methods = BoxMethods;
  62.         iBoxMethods->name = BoxName;
  63.         iBoxMethods->intersect = BoxIntersect;
  64.         iBoxMethods->normal = BoxNormal;
  65.         iBoxMethods->enter = BoxEnter;
  66.         iBoxMethods->bounds = BoxBounds;
  67.         iBoxMethods->stats = BoxStats;
  68.         iBoxMethods->checkbounds = FALSE;
  69.         iBoxMethods->closed = TRUE;
  70.     }
  71.     return iBoxMethods;
  72. }
  73.  
  74. int
  75. BoxIntersect(box, ray, mindist, maxdist)
  76. Box *box;
  77. Ray *ray;
  78. Float mindist, *maxdist;
  79. {
  80.     BoxTests++;
  81.     if (BoundsIntersect(ray, box->bounds, mindist, maxdist)) {
  82.         BoxHits++;
  83.         return TRUE;
  84.     }
  85.     return FALSE;
  86. }
  87.  
  88. int
  89. BoxNormal(box, pos, nrm, gnrm)
  90. Vector *pos, *nrm, *gnrm;    /* point of intersection */
  91. Box *box;
  92. {
  93.     nrm->x = nrm->y = nrm->z = 0.;
  94.  
  95.     if (equal(pos->x, box->bounds[HIGH][X]))
  96.         nrm->x = 1.;
  97.     else if (equal(pos->x, box->bounds[LOW][X]))
  98.         nrm->x = -1.;
  99.     else if (equal(pos->y, box->bounds[HIGH][Y]))
  100.         nrm->y = 1.;
  101.     else if (equal(pos->y, box->bounds[LOW][Y]))
  102.         nrm->y = -1.;
  103.     else if (equal(pos->z, box->bounds[HIGH][Z]))
  104.         nrm->z = 1.;
  105.     else if (equal(pos->z, box->bounds[LOW][Z]))
  106.         nrm->z = -1.;
  107.     else
  108.         RLerror(RL_WARN, "Confusion in nrmbox!\n");
  109.     *gnrm = *nrm;
  110.     return FALSE;
  111. }
  112.  
  113. /*
  114.  * Determine if ray enters (TRUE) or leaves (FALSE) box at pos
  115.  */
  116. int
  117. BoxEnter(box, ray, mind, hitd)
  118. Box *box;
  119. Ray *ray;
  120. Float mind, hitd;
  121. {
  122.     Vector pos;
  123.  
  124.     VecAddScaled(ray->pos, mind, ray->dir, &pos);
  125.     return OutOfBounds(&pos, box->bounds);
  126. }
  127.  
  128. void
  129. BoxBounds(box, bounds)
  130. Box *box;
  131. Float bounds[2][3];
  132. {
  133.     BoundsCopy(box->bounds, bounds);
  134. }
  135.  
  136. char *
  137. BoxName()
  138. {
  139.     return boxName;
  140. }
  141.  
  142. void
  143. BoxStats(tests, hits)
  144. unsigned long *tests, *hits;
  145. {
  146.     *tests = BoxTests;
  147.     *hits = BoxHits;
  148. }
  149.  
  150. void
  151. BoxMethodRegister(meth)
  152. UserMethodType meth;
  153. {
  154.     if (iBoxMethods)
  155.         iBoxMethods->user = meth;
  156. }
  157.